<?php
class Application {
    private static $appKey = '';
    /**
     * 应用程序构造函数
     */
    public function __construct() {
        if (defined('APP_LOCK_FILE') && '' != APP_LOCK_FILE) {
            $appLock = APP_LOCK_FILE;
        } else {
            $appLock = WEBLIB_DIR . '/App.lock.php';
        }
        if (false == file_exists($appLock)) {
            $appKey = md5(uniqid(microtime(), true));
            $lockContents = "<?php\n//" . $appKey;
            if (false == is_dir(WEBLIB_DIR) && false == @mkdir(WEBLIB_DIR, 0777, true)) {
                die('目录"' . WEBLIB_DIR . '"不存在，且创建失败，请手工创建，并设置目录为可写');
            }
            if (false == is_writeable(WEBLIB_DIR)) {
                die('目录"' . WEBLIB_DIR . '"不可写,请设置目录可写');
            }

            $this->init();
            file_put_contents($appLock, $lockContents);
        } else {
            if(false == is_dir(RUNTIME_DIR) || false == is_dir(DATA_DIR) || false == is_dir(TMP_DIR)) 
                $this->init();
            $lockContents = file_get_contents($appLock);
            $appKey = substr($lockContents, 8);
        }
        self::$appKey = $appKey;
    }
    
    /**
     * 获取程序ID
     * @return String
     */
    public static function getKey() {
        return self::$appKey;
    }
    
    /**
     * 应用程序初始化
     */
    public function init() {
        if (false == is_dir(ACTION_DIR)) mkdir(ACTION_DIR, 0777, true);
        if (false == is_dir(TABLE_DIR))  mkdir(TABLE_DIR,  0777, true);
        if (false == is_dir(CLASS_PATH)) mkdir(CLASS_PATH, 0777, true);
        if (false == is_dir(TPL_DIR))    mkdir(TPL_DIR,    0777, true);
        if (false == is_dir(USER_CONF_DIR)) mkdir(USER_CONF_DIR, 0777, true);
        if (false == is_dir(RUNTIME_DIR)) {
            if (is_writeable(WEBLIB_DIR)) mkdir(RUNTIME_DIR, 0777, true);
            else die('目录"' . WEBLIB_DIR . '"不可写,请设置目录可写');
        }
        if(is_writeable(RUNTIME_DIR)){
            if (false == is_dir(DATA_DIR)) mkdir(DATA_DIR, 0777, true);
            if (false == is_dir(TMP_DIR))  mkdir(TMP_DIR,  0777, true);
        } else {
            die('运行时目录"' . RUNTIME_DIR . '"存在,但不可写，请设置目录权限为可写');
        }
        @touch(APPCONF_FILE);
        @touch(APPFUNC_FILE);
        @touch(APPCONST_FILE);
    }
    
    /**
     * 程序运行
     */
    public function run() {
        ini_set('session.cookie_domain', Config::get('SESSION_COOKIE_DOMAIN'));
        ini_set('allow_call_time_pass_reference', 1);
        $_SERVER['PHP_SELF'] = $_SERVER['SCRIPT_NAME'] . $_SERVER['PATH_INFO'];
        try{
            if (false == Config::get('DEBUG')) @ini_set('display_errors', false);
            Url::dispatchUrl();
            $this->loadUserConst();
            $this->loadUserFunc();
            if (!defined('MODULE_NAME')) define('MODULE_NAME', ucfirst($_GET[Config::get('VAR_MODULENAME')]));
            if (!defined('ACTION_NAME')) define('ACTION_NAME', $_GET[Config::get('VAR_ACTIONNAME')]);
            if ('' == MODULE_NAME || '' == ACTION_NAME) 
                die('请设置默认模块(DEFAULT_MODULE)及默认方法(DEFAULT_ACTION)');
            if (Config::get('SESSION_AUTOSTART')) Session::start();
            $moduleName = MODULE_NAME . 'Action';
            $action = new $moduleName();
            $sysClass = sysClassPath();
            if (isset($sysClass[$moduleName])) {
                $action->setPrefix('do');
                $action->setSuffix('Action');
            } else {
                $action->setPrefix(Config::get('ACTION_PREFIX'));
                $action->setSuffix(Config::get('ACTION_SUFFIX'));
            }
            $action->run();
            self::afterRun();
        } catch (Exception $e) {
            echo $e->getMessage();
        }
    }
    
    private static function afterRun() {
        if(Config::get('LOG_QUERY') && false == Action::$isAjax && Config::get('DEBUG'))Logger::dumpLog();
        if(Config::get('LOG_QUERY') && (Action::$isAjax || false == Config::get('DEBUG'))) Logger::dumpToFile(basename($_SERVER['SCRIPT_FILENAME']) . '.debug.log');
        if (Config::get('DEBUG') && false == Action::$isAjax) {
            $GLOBALS['END_AT'] = microtime(true);
            $GLOBALS['END_MEM'] = memory_get_usage(true);
            echo '程序运行耗时:' . ($GLOBALS['END_AT'] - $GLOBALS['START_AT']) . 'seconds<br />
                  程序运行内存:' . sprintf('%.4f', ($GLOBALS['END_MEM'] - $GLOBALS['START_MEM'])/1024) . 'KB';
        }
        session_write_close();
        Cache::close();
        Dao::close();
    }

    private function loadUserFunc() {
        if (file_exists(APPFUNC_FILE)) {
            include APPFUNC_FILE;
        }
    }
    
    private function loadUserConst() {
        if (file_exists(APPCONST_FILE)) {
            include APPCONST_FILE;
        }
    }
};
?>